// <com.woyouqiu.Copyright>
// --------------------------------------------------------------
// <copyright>上海有求网络科技有限公司 2015</copyright>
// <Solution>Vecen.BangChuang</Solution>
// <Project>Vecen.BangChuang.Application</Project>
// <FileName>FavoriteAppService.cs</FileName>
// <CreateTime>2017-04-27 21:52</CreateTime>
// <Author>何苗</Author>
// <Email>hemiao@woyouqiu.com</Email>
// <log date="2017-04-27 21:52" version="00001">创建</log>
// --------------------------------------------------------------
// </com.woyouqiu.Copyright>

using System.Linq;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Runtime.Session;
using Abp.UI;
using Vecen.BangChuang.BangChuang.Classes;
using Vecen.BangChuang.BangChuang.DomainServices.Agents;
using Vecen.BangChuang.BangChuang.Mall.Dtos;
using Vecen.BangChuang.BangChuang.Products;
using Vecen.BangChuang.Enums;

namespace Vecen.BangChuang.BangChuang.Mall {

    /// <summary>
    /// 收藏相关操作
    /// </summary>
    [AbpAuthorize()]
    public class FavoriteAppService: BangChuangAppServiceBase, IFavoriteAppService {

        private readonly IRepository<Favorite> _favoriteRepository;
        private readonly IRepository<Product> _productRepository;
        private readonly IRepository<MicroClass> _classRepository;
        private readonly AgentDomainService _agentDomainService;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="favoriteRepository"></param>
        /// <param name="productRepository"></param>
        /// <param name="classRepository"></param>
        /// <param name="agentDomainService"></param>
        public FavoriteAppService(IRepository<Favorite> favoriteRepository,
            IRepository<Product> productRepository,
            IRepository<MicroClass> classRepository,
            AgentDomainService agentDomainService) {
            _favoriteRepository = favoriteRepository;
            _productRepository = productRepository;
            _classRepository = classRepository;
            _agentDomainService = agentDomainService;
        }

        /// <summary>
        /// 添加收藏
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task FavoriteAsync(FavoriteRequestDto input) {
            var isFavorited = _favoriteRepository.GetAll()
                .Where(c => c.FavoriteType == input.FavoriteType.ToString())
                .Where(c => c.ObjectId == input.ObjectId)
                .Any(c => c.CreatorUserId == AbpSession.UserId);
            if(isFavorited) {
                throw new UserFriendlyException("请求失败!", $"您已经收藏过该{input.FavoriteType.Description()}了!");
            }
            if(_favoriteRepository.GetAll().Count(c => c.CreatorUserId == AbpSession.UserId) > 100) {
                throw new UserFriendlyException("请求失败!", "您的收藏内容数量超过100了!");
            }

            Favorite favorite = new Favorite();
            favorite.FavoriteType = input.FavoriteType.ToString();
            favorite.ObjectId = input.ObjectId;
            await _favoriteRepository.InsertAndGetIdAsync(favorite);
        }

        /// <summary>
        /// 获得收藏的商品列表
        /// </summary>
        /// <returns></returns>
        public async Task<ListResultDto<FavoriteProductOutPut>> GetFavoriteProductsAsync() {
            var userType = await _agentDomainService.GetUserTypeAsync(AbpSession.GetUserId());
            var query = from favorite in _favoriteRepository.GetAll().Where(c => c.CreatorUserId == AbpSession.UserId)
                join product in _productRepository.GetAllIncluding(c=>c.Category) on favorite.ObjectId equals product.Id
                select new FavoriteProductOutPut {
                    Id = favorite.Id,
                    FavoriteTime = favorite.CreationTime,
                    ProductId = favorite.ObjectId,
                    Name = product.Name,
                    IsFavorite = true,
                    ProductType = product.ProductType,
                    Status = product.Status,
                    Description = product.Description,
                    Category = product.Category.Name,
                    Price = product.ExFactoryPrice
                };
            var dtos = await Task.Run(() => query.ToList());
            foreach (var dto in dtos)
            {
                dto.HeaderImageId =
                    await AttachmentManager.GetIdAsync(Product.ProductHeaderAttachmentType, dto.ProductId);
            }
            return new ListResultDto<FavoriteProductOutPut>(dtos);
        }

        /// <summary>
        /// 获得收藏的课程列表
        /// </summary>
        /// <returns></returns>
        public Task<ListResultDto<FavoriteClassOutPut>> GetFavoriteClassesAsync() {
            var query = from favorite in _favoriteRepository.GetAll().Where(c => c.CreatorUserId == AbpSession.UserId)
                join microClass in _classRepository.GetAll() on favorite.ObjectId equals microClass.Id
                select new FavoriteClassOutPut {
                    Id = favorite.Id, FavoriteTime = favorite.CreationTime, ClassId = favorite.ObjectId,
                    ClassName = microClass.Title
                };
            return Task.Run(() => new ListResultDto<FavoriteClassOutPut>(query.ToList()));
        }

        /// <summary>
        /// 取消收藏
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task CancelAsync(int id) {
            await _favoriteRepository.DeleteAsync(c => c.Id == id && c.CreatorUserId == AbpSession.UserId);
        }

        /// <summary>
        /// 取消收藏
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task CancelWithTypeAsync(FavoriteRequestDto input) {
            await _favoriteRepository.DeleteAsync(c => c.FavoriteType == input.FavoriteType.ToString()
                                                       && c.ObjectId == input.ObjectId
                                                       && c.CreatorUserId == AbpSession.UserId);
        }
    }
}